using Core.GameObjects.Steering;
using Microsoft.Xna.Framework;

namespace Core.GameObjects
{
    public class MovingGameObject : DrawableGameObject
    {
        public Vector2 Velocity { get { return _Velocity; } }
        public Vector2 Heading { get { return _Heading; } }
        public Vector2 Side { get { return _Side; } }
        public float Mass { get { return _Mass; } }
        public float MaxSpeed { get { return _MaxSpeed; } }
        public float MaxForce { get { return _MaxForce; } }
        public float MaxTurnRate { get { return _MaxTurnRate; } }

        protected Vector2 _Velocity;
        protected Vector2 _Heading; //A Normalized vector pointing in the direction the entity is heading
        protected Vector2 _Side; //A vector perpendicular to the heading vector
        protected float _Mass;
        protected float _MaxSpeed; //The Maximum speed at which this object can travel
        protected float _MaxForce; //The maximum force this entity can produce to power itself
        protected float _MaxTurnRate; //the maximum rate (radians per second) at which this vehical can rotate

        protected SteeringBehaviors _Steering;

        public MovingGameObject(int id, string name)
            : base(id, name)
        { 
        
        }

        public override void Update(GameTime gameTime)
        {
            float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
            //calculate the combined force from each steering behavior in the vehicle's list
            Vector2 SteeringForce = _Steering.Calculate();
            //Acceleration = Force/Mass (Derived from F=M*A)
            Vector2 Acceleration = SteeringForce / _Mass;
            //Update Velocity
            _Velocity += Acceleration * elapsed;
            //Make sure the speed does not exceed our max velocity
            Vector2Utilities.Truncate(_Velocity, _MaxSpeed);
            //Update our current position
            //TODO: Figure out how to Update the current position. Will probably involve _SubX/_SubY values for partial tile movement.

            //Update the Heading and Side values if velocity greater then a very small value
            if (_Velocity.LengthSquared() > 0.000001f)
            {
                _Heading = Vector2.Normalize(_Velocity);
                _Side = Vector2Utilities.Perpendicular(_Heading);
            }

            base.Update(gameTime);
        }
    }
}
